package 多线程3;
//wait notify 协调多个线程之间执行的先后顺序 需要搭配synchronized来使用

//线程安全版本的单例模式
//饿汉模式本身就是线程安全的,因为这只有一个读操作
//懒汉模式就不是线程安全的,主要体现在实例未创建的时候,如果多个线程并发的调用getInstance就可能导致实例被创建多份
public class TestDemo1 {
    //懒汉模式
    static class Singleton {
        private Singleton() {

        }
//给Singleton前面在加上个volatile,保证内存可见性
        private static volatile Singleton instance = null;

        //后续线程再次调用getInstance()的时候,进行if判断,看似在在访问instance的值,
        // 有可能因为编译器优化,导致直接读的是寄存器里边缓存的值,而不是内存里边修改过的值.
        public static Singleton getInstance() {
            if (instance == null) {//区分首批调用还是后续调用,决定要不要加锁
                synchronized (TestDemo1.Singleton.class) {
                    if (instance == null) {//第一批调用的这些线程,其中谁是那个能获取到锁的幸运儿
                        instance = new TestDemo1.Singleton();
                    }
                }
            }
            return instance;
        }

        public static void main(String[] args) {
            //通过这个方法来获取到实例,就能保证只有唯一实例
            Singleton instance = Singleton.getInstance();
        }
    }
}
